From ab6f771413bb5a69c9be3365f0f899d5d318f73e Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 21 Aug 2014 17:31:50 +0200 Subject: [PATCH] wayland: create a wl_subsurface interface for GDK_WINDOW_SUBSURFACE windows This subsurface is currently dependent on the transient_for parent, so the subsurface is repositioned relative to it. https://bugzilla.gnome.org/show_bug.cgi?id=729215 --- gdk/wayland/gdkwindow-wayland.c | 70 ++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 2 deletions(-) diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index 055352227e..9c29b96a2c 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -95,6 +95,8 @@ struct _GdkWindowImplWayland struct xdg_popup *xdg_popup; struct gtk_surface *gtk_surface; + struct wl_subsurface *subsurface; + unsigned int mapped : 1; unsigned int use_custom_surface : 1; unsigned int pending_commit : 1; @@ -784,6 +786,37 @@ static const struct wl_surface_listener surface_listener = { surface_leave }; +static void +gdk_wayland_window_create_subsurface (GdkWindow *window) +{ + GdkWindowImplWayland *impl, *parent_impl = NULL; + GdkWaylandDisplay *display_wayland; + + if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_SUBSURFACE) + return; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + + if (!impl->surface) + return; /* Bail out, surface and subsurface will be created later when shown */ + + if (impl->subsurface) + return; + + if (impl->transient_for) + parent_impl = GDK_WINDOW_IMPL_WAYLAND (impl->transient_for->impl); + + if (parent_impl) + { + display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); + impl->subsurface = + wl_subcompositor_get_subsurface (display_wayland->subcompositor, + impl->surface, parent_impl->surface); + wl_subsurface_set_position (impl->subsurface, window->x, window->y); + wl_subsurface_set_desync (impl->subsurface); + } +} + static void gdk_wayland_window_create_surface (GdkWindow *window) { @@ -796,6 +829,9 @@ gdk_wayland_window_create_surface (GdkWindow *window) gdk_wayland_window_sync_opaque_region (window); gdk_wayland_window_sync_input_region (window); + + if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_SUBSURFACE) + gdk_wayland_window_create_subsurface (window); } static void @@ -1070,7 +1106,8 @@ gdk_wayland_window_map (GdkWindow *window) else transient_for = impl->transient_for; - if (transient_for) + if (transient_for && + GDK_WINDOW_TYPE (window) != GDK_WINDOW_SUBSURFACE) { struct wl_seat *grab_input_seat = find_grab_input_seat (window, transient_for); if (grab_input_seat && @@ -1083,7 +1120,8 @@ gdk_wayland_window_map (GdkWindow *window) } } - gdk_wayland_window_create_xdg_surface (window); + if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_SUBSURFACE) + gdk_wayland_window_create_xdg_surface (window); mapped: impl->mapped = TRUE; @@ -1099,6 +1137,9 @@ gdk_wayland_window_show (GdkWindow *window, if (!impl->surface) gdk_wayland_window_create_surface (window); + if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_SUBSURFACE) + gdk_wayland_window_create_subsurface (window); + gdk_wayland_window_map (window); _gdk_make_event (window, GDK_MAP, NULL, FALSE); @@ -1125,6 +1166,12 @@ gdk_wayland_window_hide_surface (GdkWindow *window) impl->xdg_popup = NULL; } + if (impl->subsurface) + { + wl_subsurface_destroy (impl->subsurface); + impl->subsurface = NULL; + } + wl_surface_destroy (impl->surface); impl->surface = NULL; @@ -1205,11 +1252,18 @@ gdk_window_wayland_move_resize (GdkWindow *window, { if (with_move) { + GdkWindowImplWayland *impl; + + impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); + /* Each toplevel has in its own "root" coordinate system */ if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_TOPLEVEL) { window->x = x; window->y = y; + + if (impl->subsurface) + wl_subsurface_set_position (impl->subsurface, x, y); } } @@ -1502,6 +1556,18 @@ gdk_wayland_window_set_transient_for (GdkWindow *window, impl->transient_for = parent; gdk_wayland_window_sync_parent (window); + + if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_SUBSURFACE) + { + if (impl->subsurface) + { + wl_subsurface_destroy (impl->subsurface); + impl->subsurface = NULL; + } + + if (parent) + gdk_wayland_window_create_subsurface (window); + } } static void -- 2.30.2